---
layout: blog-default
---
<div class="m-post">
    <div class="main js-main">
        <div class="col-1">
            <article itemscope itemtype="http://schema.org/BlogPosting">
                <meta itemprop="mainEntityOfPage" itemscope itemType="https://schema.org/WebPage"/>
                <header class="article-header">
                    <h1 itemprop="headline" itemprop="name headline">{{ page.title }}</h1>
                    {% include blog/article-data.html %}
                </header>
                <div class="m-article-content js-article-content" itemprop="articleBody">
                    {{ content }}
                </div>
                <footer>
                    {% if page.modify_date %}
                        <span>
                            Last updated
                            <time datetime="{{ page.modify_date | date_to_xmlschema }}" itemprop="dateModified">
                                {{ page.modify_date | date: "%b %-d, %Y" }}
                            </time>
                        </span>
                    {% else %}
                        <meta itemprop="dateModified" content="{{ page.date | date_to_xmlschema }}">
                    {% endif %}
                    <div class="article-license">
                        {% include blog/license.html %}
                    </div>
                </footer>
                {% if page.comment != false %}
                    <section>{% include utils/comment-disqus.html %}</section>
                {% endif %}
            </article>
        </div>
        <div class="col-2">
            <aside class="js-article-aside">
                <div class="m-toc js-toc"></div>
            </aside>
        </div>
    </div>
</div>

<script src="//cdn.bootcss.com/toc/0.3.2/toc.min.js"></script>
<script type="text/javascript">
    window.throttle = function(func, wait) {
        var args,
            result,
            thisArg,
            timeoutId,
            lastCalled = 0;

        function trailingCall() {
            lastCalled = new Date;
            timeoutId = null;
            result = func.apply(thisArg, args);
        }
        return function() {
            var now = new Date,
                remaining = wait - (now - lastCalled);

            args = arguments;
            thisArg = this;

            if (remaining <= 0) {
                clearTimeout(timeoutId);
                timeoutId = null;
                lastCalled = now;
                result = func.apply(thisArg, args);
            }
            else if (!timeoutId) {
                timeoutId = setTimeout(trailingCall, remaining);
            }
            return result;
        };
    }
    $(function() {
        var $window = $(window);
        var $pageStage = $('.js-page-stage');
        var $pageMain = $('.js-main');
        var $pageFooter = $('.js-page-footer');
        var $articleContent = $('.js-article-content');
        var $articleAside = $('.js-article-aside');
        var $toc = $('.js-toc');
        var hasTitle = $articleContent.find('h1, h2, h3').length > 0;

        function asideSticky() {
            return $window.outerWidth() > 1150 && $pageStage.hasClass('has-toc');
        }
        function setTocClass() {
            if (hasTitle) {
                !$pageStage.hasClass('has-toc') && $pageStage.addClass('has-toc');
            }
        }

        setTocClass();

        function setAsideTOC() {
            var asideTop,
                asideLeft,
                scrollBottom,
                asideBottomTop,
                lastScrollTop;

            function init() {
                var asideOffset = $articleAside.offset();
                var footerOffset = $pageFooter.offset();
                var mainOffset = $pageMain.offset();
                asideTop = mainOffset.top;
                asideHeight = $toc.outerHeight() + parseInt($articleAside.css('padding-top'), 10) + parseInt($articleAside.css('padding-bottom'), 10);
                asideLeft = mainOffset.left + $pageMain.outerWidth() - $articleAside.outerWidth() - parseInt($pageMain.css('padding-right'), 10);
                scrollBottom = footerOffset.top - asideHeight;
                asideBottomTop = scrollBottom - mainOffset.top;
            }
            function setAside(force) {
                force !== true && (force = false);
                var scrollTop = $window.scrollTop();
                if (scrollTop >= asideTop && scrollTop <= scrollBottom) {
                    (!force && lastScrollTop >= asideTop && lastScrollTop <= scrollBottom) ||
                        $articleAside.addClass('fixed').css({
                            left: asideLeft + 'px',
                            top: 0
                        });
                } else if (scrollTop < asideTop) {
                    (!force && lastScrollTop < asideTop) ||
                        $articleAside.removeClass('fixed').css({
                            left: 0,
                            top: 0
                        });
                } else {
                    (!force && lastScrollTop > scrollBottom) ||
                        $articleAside.removeClass('fixed').css({
                            left: 0,
                            top: asideBottomTop + 'px'
                        });
                }
                lastScrollTop = scrollTop;
            }
            asideSticky() && (init(), setAside());
            $window.on('scroll', function() {
                asideSticky() && setAside();
            });
            $window.on('resize', throttle(function() {
                setTocClass();
                asideSticky() && (init(), setAside(true));
            }, 100));
            setTimeout(init, 4000);
        }
        setTimeout(setAsideTOC, 1000);

        $toc.toc({
            'selectors': 'h1,h2,h3',
            'container': '.js-article-content',
        });
    });
</script>
{% if page.key and site.leancloud.app_id and site.leancloud.app_key and site.leancloud.app_class and site.isdebug == false %}
    <script src="https://cdn1.lncld.net/static/js/av-min-1.2.1.js"></script>
    <script type="text/javascript">
        $(function() {
            // 初始化
            AV.init({
                appId: '{{ site.leancloud.app_id }}',
                appKey: '{{ site.leancloud.app_key }}'
            });
            // 查询
            var query = new AV.Query('{{ site.leancloud.app_class }}');
            query.equalTo('key', '{{ page.key }}');
            query.first().then(function(result) {
                if (result) {
                    addOne(result)
                } else {
                    //新建
                    var Blog = AV.Object.extend('{{ site.leancloud.app_class }}');
                    var blog = new Blog();
                    blog.set('title', '{{ page.title }}');
                    blog.set('key', '{{ page.key }}');
                    blog.set('views', 0);
                    blog.save().then(function(page) {
                        addOne(page)
                    }, function(error) {
                        if (error) {
                            throw error;
                        }
                    });
                }

                function addOne(page) {
                    page.increment('views', 1);
                    page.fetchWhenSave(true);
                    page.save().then(function(page) {
                        $("#post-key-{{ page.key }}").text(page.attributes.views);
                    }, function(error) {
                        if (error) {
                            throw error;
                        }
                    });
                }
            }, function(error) {
                if (error) {
                    throw error;
                }
            });
        });
    </script>
{% endif %}
